<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script>
    // 栈数据结构是一种遵从 后进先出 原则（想想杯子）的有序集合，遵从 LIFO 原则
    // 添加的时候是从末尾加入，移除的时候是从栈顶移除，同时返回被移除的元素
    // 创建一个基于数组的栈
    class StackArray {
        constructor() {
            this.items = [];
        }
        // 推入元素
        push = (ele) => {
            this.items.push(ele);
        }
        // 删除元素，同时返回被移除的元素
        pop = () => {
            return this.items.pop();
        }
        // 查看栈顶元素
        peek = () => {
            if (this.items.length === 0) {
                return null
            }
            return this.items[this.items.length - 1];
        }
        // 检查是否为空栈
        isEmpty = () => {
            return this.items.length === 0;
        }
        // 栈的长度
        size = () => {
            return this.items.length;
        }
        // 清空栈
        clear = () => {
            this.items.splice(0, this.items.length)
        }
    }
    // const stack = new StackArray()
    // stack.push('ooo')
    // stack.push(111)
    // stack.pop()
    // stack.push(222)
    // stack.clear()
    // console.log(stack);

    // 设计基于对象的栈结构
    class StackObject {
        #count = 0; // 定义私有变量，序号
        constructor() {
            this.items = {};    // 定义结构
        }
        // 方法
        push = (ele) => {
            this.items[this.#count] = ele;
            this.#count++;
        }
        size = () => {
            return this.#count;
        }
        isEmpty = () => {
            return this.#count === 0;
        }
        pop = () => {
            if (this.#count === 0) {
                return null
            }
            this.#count--
            const delEle = this.items[this.#count];
            delete this.items[this.#count]
            return delEle;
        }
        peek = () => {
            if (this.isEmpty()) {
                return null
            }
            return this.items[this.#count - 1]
        }
        clear = () => {
            this.#count = 0
            while (!this.isEmpty()) {
                this.pop()
            }
        }
        toString = () => {
            if (this.isEmpty()) {
                return "{}"
            }
            let str = "{"
            for (let i = 0; i < this.#count; i++) {
                str += `${i}: ${this.items[i]}, `
            }
            str = str.slice(0, str.length - 2)
            return str + "}"
        }
    }
    let y = new StackObject()

    y.push(3)
    y.push(223)
    console.log(y.items);
    
    // 栈的应用
    // 进制转化算法
    function baseConvert(decNum, base, digit = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") {
        let remStack = new StackObject();
        let number = decNum;
        let numStr = ""
        if (base > digit.length || base < 2 || decNum < 1) {
            return ''
        }
        while (number > 0) {
            remStack.push(Math.floor(number % base))
            number = Math.floor(number / base)
        }
        while (!remStack.isEmpty()) {
            numStr += digit[remStack.pop()]
        }
        return numStr;
    }
    const lee = 1233298733333333333333333
    console.log(baseConvert(lee, 32));
</script>

</html>